import * as EBML from 'ts-ebml'
import RecordRTC from 'recordrtc'

window.EBML = EBML

export class BottomBarControl {
  constructor({ el, pc, video, title, vm }) {
    this.vm = vm
    this.container = el
    this.title = title
    this.pc = pc
    this.videoEl = video

    this.netLastResult = null

    this.muted = false
    this.recorder = null
    this.isRecording = false
    this.recordData = null
    this.recordBlob = null
    this.timer = null

    this.event = {
      getMsg: (msg) => {
        return msg
      }
    }
  }

  // 设置DOM元素
  loadContainer(container) {
    this.container = container
  }

  // 声音控制
  isMuted() {
    this.muted = !this.muted
    this.videoEl.muted = this.muted
    this.vm.isMuted = this.muted
  }

  // 录像
  recordVideo(flag) {
    const $this = this
    if (!$this.isRecording && $this.vm.cameraTotal > 1) {
      this.vm.stopCarousel()
      this.vm.$confirm('当前有多个分页，只能录像当前播放视频，执行录像将停止轮巡, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        closeOnPressEscape: false,
        type: 'warning'
      }).then(() => {
        $this.recordIng(flag)
      }).catch(() => {
        this.vm.$parent.$parent.$refs['layoutTools'].carousel()
      })
    } else {
      $this.recordIng(flag)
    }
  }

  recordIng(flag) {
    if (this.isRecording) {
      this.stopRecord()
    } else {
      this.startRecord(flag)
    }
  }

  // 开始录像
  startRecord(flag) {
    if (!this.isRecording && !this.recorder) {
      this.recorder = this.record(flag)
      this.isRecording = true
      this.vm.isRecording = true
    }
  }

  // 结束录像
  stopRecord() {
    if (!this.isRecording) {
      return
    }
    if (!this.recorder) {
      return
    }
    this.isRecording = false
    this.vm.isRecording = false
    this.recorder.stop()
    this.recorder = null
  }

  // 录像过程
  record(flag) {
    const stream = this.videoEl.captureStream(60)
    let options = { mimeType: 'video/webm;codecs=vp9' }
    if (!MediaRecorder.isTypeSupported(options.mimeType)) {
      options = { mimeType: 'video/webm;codecs=vp8' }
    }
    if (!MediaRecorder.isTypeSupported(options.mimeType)) {
      options = { mimeType: 'video/webm' }
    }
    if (!MediaRecorder.isTypeSupported(options.mimeType)) {
      options = { mimeType: '' }
    }
    let recorder = RecordRTC(stream, Object.assign({
      type: 'video'
    }, options))
    recorder.startRecording()
    recorder.stop = () => {
      recorder.stopRecording(() => {
        RecordRTC.getSeekableBlob(recorder.getBlob(), seekableBlob => {
          recorder.destroy()
          recorder = null
          if (flag) {
            this.recordBlob = seekableBlob
          } else {
            const url = URL.createObjectURL(seekableBlob)
            this._download(url, `${this.title}-${new Date().getTime()}.mp4`)
            window.URL.revokeObjectURL(url)
          }
        })
      })
    }
    return recorder
  }

  // 抓拍
  capture(flag) {
    const $this = this
    if ($this.vm.cameraTotal > 1) {
      this.vm.stopCarousel()
      this.vm.$confirm('当前有多个分页，只能抓拍当前播放视频，执行抓拍将停止轮巡, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        closeOnPressEscape: false,
        type: 'warning'
      }).then(() => {
        $this.captureImage(flag)
      }).catch(() => {
        this.vm.$parent.$parent.$refs['layoutTools'].carousel()
      })
    } else {
      $this.captureImage(flag)
    }
  }

  captureImage(flag) {
    const width = this.videoEl.videoWidth
    const height = this.videoEl.videoHeight
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = width
    canvas.height = height
    ctx.drawImage(this.videoEl, 0, 0, width, height)
    const url = canvas.toDataURL(`image/png`)
    if (flag) {
      return canvas.toDataURL(`image/png`)
    } else {
      this._download(url, `${this.title}-${new Date().getTime()}.png`)
      window.URL.revokeObjectURL(url)
    }
  }

  // 下载
  _download(url, fileName) {
    const a = document.createElement('a')
    a.href = url
    a.download = fileName
    a.click()
  }

  // 全屏方法
  fullScreen() {
    this.vm.stopCarousel()
    const isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen
    if (isFull) {
      document.exitFullscreen ? document.exitFullscreen() : document.mozCancelFullScreen ? document.mozCancelFullScreen() : document.webkitExitFullscreen ? document.webkitExitFullscreen() : ''
    } else {
      this.videoEl = this.videoEl || window
      const fullscreen = this.container.requestFullscreen ||
        this.container.mozRequestFullScreen ||
        this.container.msRequestFullscreen ||
        this.container.oRequestFullscreen ||
        this.container.webkitRequestFullscreen
      if (fullscreen) {
        // this.videoEl.parentNode.parentNode
        fullscreen.call(this.container)
      } else {
        if (typeof window.ActiveXObject !== 'undefined') {
          const script = new ActiveXObject('WScript.Shell')
          if (script) {
            script.SendKeys('{F11}')
          }
        }
      }
    }
  }

  destroy() {
    if (this.pc) {
      this.pc.onaddstream = null
      this.pc.oniceconnectionstatechange = null
      this.pc.addTransceiver = null
      this.pc.createOffer = null
      this.pc.setLocalDescription = null
      this.pc.setRemoteDescription = null
      this.pc.close()
      this.pc = null
    }
    clearInterval(this.timer)
    this.timer = null
    this.container = null
    this.title = ''
    this.videoEl = null
    this.netLastResult = null

    this.muted = false
    this.recorder = null
    this.isRecording = false
    this.recordData = null
    this.recordBlob = null
  }

  // 获取帧率和码率
  _setNetInformationListener() {
    this.timer = setInterval(() => {
      const pc = this.pc
      if (!pc) {
        clearInterval(this.timer)
        this.timer = null
        return
      }
      const recv = pc.getReceivers()[1]
      try {
        recv.getStats().then(res => {
          res.forEach(report => {
            let bytes
            let framesDecoded
            if (report.type === 'inbound-rtp') {
              if (report.mediaType === 'video') {
                const now = report.timestamp
                bytes = report.bytesReceived
                framesDecoded = report.framesDecoded
                if (this.netLastResult && this.netLastResult.has(report.id)) {
                  const deltaT = now - this.netLastResult.get(report.id).timestamp
                  const bitrate = 8 * (bytes - this.netLastResult.get(report.id).bytesReceived) / deltaT
                  const frame = framesDecoded - this.netLastResult.get(report.id).framesDecoded
                  this.emit('setMsg', {
                    frame: `${frame} FPS`,
                    bitrate: `${bitrate.toFixed(3)} Kbps`
                  })
                }
              }
            }
          })
          this.netLastResult = res
        })
      } catch (err) {
        console.log(err)
        clearInterval(this.timer)
        this.timer = null
      }
    }, 1000)
  }

  on(event, callback) {
    this.event[event] = callback
  }

  eval(method) {
    try {
      eval(`this.${method}()`)
    } catch (e) {
      console.error(e)
    }
  }

  emit(event, data) {
    try {
      this.event[event].call(null, data)
    } catch (e) {
      console.error(e)
    }
  }
}
